package CutLoad.components.container
{
	import CutLoad.Base;
	import CutLoad.CutLoad;
	import CutLoad.components.CRender;
	import CutLoad.cookies.CArray;
	import CutLoad.cookies.LayoutTable;
	import CutLoad.cookies.Painter;
	import CutLoad.transitions.ITransition;
	
	import flash.display.Sprite;

	/**
	 * 布局容器
	 * @author smallerbird mail:smallerbird@gmail.com  site:www.mkigm.com QQ群:49983196
	 * 
	 */	
	public class Container extends Base
	{
		private var LT:LayoutTable
		//外观尺寸
		private var displayWidth:Number=0,displayHeight:Number=0;
		/**
		 * 内容遮蔽,用于超过窗口大小的部分会被隐藏
		 */		
		protected var spMask:Sprite=null;
		//
		/**
		 * 子元件占的实宽高
		 */		
		protected var takeWidth:Number=0,takeHeight:Number=0;
		/**
		 * 放置子元素的容器
		 */		
		protected var spContent:Sprite
		//辅助线
		private var spGuide:Sprite=null;
		//辅助线:实际
		private var spTakeGuide:Sprite=null;
		//效果
		private var transition:ITransition;
		/**
		 * 保存子元素 
		 */		
		protected var arr:CArray=new CArray();
		/**
		 * 背景 
		 */		
		protected var bakRender:CRender;
		/**
		 * 获得占位的方块,注：当在布局中时会常常用到，用来占位的。
		 * @param ww 宽
		 * @param hh 高
		 * @param cc 颜色
		 * @param alpha 透明度
		 * @return 
		 * 
		 */		
		public static function getSpaceTile(ww:Number,hh:Number,cc:Number=0xffffff,alpha:Number=0):Base{
			return Base.getBase(Painter.getRect(ww,hh,cc,alpha));
		}
		/**
		 * 以一个元件的宽和高来设置占位方块 
		 * @param base 参考元件的宽高
		 * @param cc 颜色
		 * @param alpha 透明度
		 * @return 
		 * 
		 */		
		public static function setSpaceTileForBase(base:Base,cc:Number=0xffffff,alpha:Number=0):Base{
			return getSpaceTile(base.getShowWidth(),base.getShowHeight(),cc,alpha);
		}
		public function Container()
		{
		}
		/**
		 * 初始化
		 * @param obj  {w:宽,h:高,lt_transition:实现ITransition接口的过渡效果} 可以为空
		 * @return 
		 * 
		 */		
		public function init(obj:Object=null):void{
			if(obj==null)  throw new Error("缺少配置属性：{w:宽,h:高}");
			if(obj.w==null||obj.h==null) throw new Error("缺少配置属性：{w:宽,h:高}");
			transition=obj.lt_transition;
			LT=new LayoutTable();
			//设置过渡效果
			setWH(obj.w,obj.h);
			//
			spContent=new Sprite();
			bakRender=new CRender();
			bakRender.init(0,0,{color:0xffffff,alpha:0,isBitmap:false},obj.w,obj.h);
			this.addChild(bakRender);
			this.addChild(spContent);
		}
		/**
		 * 添加一个元件进入容器 
		 * @param base 元件 
		 * @param isUpdate 是否立即显示正确的位置，注：如果批量添加的话，可以在添加最后一个是设为true,前面的设为flash,这样可以提高效率
		 * @param obj {x:x坐标,y:坐标,t:对齐类型}   对齐类型:0居中,1左上,2上中,3右上,4右中,5右下,6下中,7左下,8左中,注：如果设置坐标，将忽略对齐类型
		 * 
		 */		
		public function append(base:Base,isUpdate:Boolean=true,obj:Object=null):void{
			if(obj==null) throw new Error("需要配置信息");
			layoutOne(base,obj)
			//保存自己的对齐信息
			base.appendOtherInfo(obj);
			spContent.addChild(base);
			arr.add(base);
			if(isUpdate) update();
		}
		/**
		 * 添加一个元件进入容器 ,用绝对坐标定位它,注：实际是调用了：append
		 * @param base 
		 * @param x
		 * @param y
		 * @param isUpdate 是否立即显示正确的位置
		 * 
		 */		
		public function appendXY(base:Base,x:Number=0,y:Number=0,isUpdate:Boolean=false):void{
			append(base,isUpdate,{x:x,y:y})
		}
		/**
		 * 获得Container子元素Group,可以从这里可以获得子元素 
		 * @return 
		 * 
		 */		
		public function getChildeGroup():CArray{
			return arr;
		}
		/**
		 * 返回装子元素的容器 
		 * @return 
		 * 
		 */		
		public function getChildeParent():Sprite{
			return spContent;
		}
		/**
		 * 将某子元素设为最顶端 
		 * @param base
		 * 
		 */		
		public function setTopDepath(base:Base):void{
			spContent.setChildIndex(base,spContent.numChildren-1);
		}
		/**
		 * 将某子元素设为指定深度值
		 * @param base
		 * @param index
		 * 
		 */		
		public function setDepath(base:Base,index:Number):void{
			if(index<0||index>spContent.numChildren-1) throw new Error("深度值设置无效!!!");
			spContent.setChildIndex(base,index);
		}
		/**
		 * 清空所有子元件 
		 * 
		 */		
		public function removeAll():void{
			if(spContent!=null){
				this.removeChild(spContent);
				spContent=null;
			}
			spContent=new Sprite();
			this.addChild(spContent);
			swapChildren_bakRender_spContent();
			arr=new CArray();
			this.takeHeight=this.takeWidth=0;
		}
		private function swapChildren_bakRender_spContent():void{
			if(bakRender!=null){
				if(this.getChildIndex(bakRender)>this.getChildIndex(spContent)){
					this.swapChildren(bakRender,spContent);
				}
			}
		}
		/**
		 * 清除一个子元素 
		 * @param base 子元素
		 * 
		 */		
		public function delChild(base:Base):Boolean{
			if(base==null) return false;
			if(!arr.del(base)) return false;
			base.killMe();
			base=null;
			this.update();
			return true;
		}
		/**
		 * 是否隐藏的部分显示 
		 * @param isOn true:不显示,flash显示
		 * 
		 */		
		public function maskOn(isOn:Boolean):void{
			if(spMask!=null){
				this.removeChild(spMask);
				spMask=null;
			}
			if(isOn){
				spMask=Painter.getRect(this.getShowWidth(),this.getShowHeight(),0xff0000,0.8);
				this.addChild(spMask);
				spContent.mask=spMask;
			}else{
				spContent.mask=null;
			}
		}
		protected function layoutOne(base:Base,obj:Object):void{
			if(obj.x==null||obj.y==null){
				if(obj.t==null){
					throw new Error("所需要属性错误!  建议：你是否在之前调用过setOtherInfo这个方法，而把保存的额外的对齐属性删除了~");
				}else{
					LT.setXY(obj.t,base,0,0,true,transition);
				}
			}else{
				base.setXY(obj.x,obj.y);
			}
		}
		/**
		 * 把容器的大小设置成为元件实际占领的宽高
		 * 
		 */		
		public function setTakeWH():void{
			//if(takeWidth==0||takeHeight==0) trace("警告:takeWidth==0||takeHeight==0");
			this.update();
			this.setWH(takeWidth,takeHeight);
			//this.showGuide(0);
		}
		/**
		 * 刷新 
		 * 
		 */		
		public function update():void{
			this.takeWidth=this.takeHeight=0;
			var arrTem:Array=arr.data;
			for(var i:Number=0;i<arrTem.length;i++){
				//获得对齐信息
				var baseTem:Base=arrTem[i]
				var objTem:Object=baseTem.getOtherInfo()
				layoutOne(baseTem,objTem)
				//
				var xx:Number=baseTem.getXYRightDown().x
				var yy:Number=baseTem.getXYRightDown().y;
				if(xx>this.takeWidth) takeWidth=xx;
				if(yy>this.takeHeight) takeHeight=yy;			
			}
			//showGuide()
		}
		/**
		 *  显示附助边框
		 * 
		 */		
		public function showGuide(alphaNum:Number=1):Sprite{
			if(spGuide!=null){
				this.removeChild(spGuide);
				spGuide=null;
			}
			spGuide=LT.DrawTable();
			spGuide.alpha=alphaNum;
			this.addChild(spGuide);
			return spGuide;
		}
		/**
		 * 是示附助边框:内部实际占的宽高
		 * 
		 */		
		public function showTakeGuide():void{
			if(spTakeGuide!=null){
				this.removeChild(spTakeGuide);
				spTakeGuide=null;
			}
			spTakeGuide=Painter.getRect(this.getTakeWidth(),this.getTakeHeight(),0xff0000,0.2);
			this.addChild(spTakeGuide);
		}
		/**
		 * 设置背景
		 *
		 */			
		public function setBak(way:uint,type:uint,config:Object):void{
			clrBak()
			bakRender=new CRender();
			bakRender.init(way,type,config,this.getShowWidth(),this.getShowHeight());
			this.addChild(bakRender);
			swapChildren_bakRender_spContent();
		}
		/**
		 * 设置一个色块的背景
		 * @param c 颜色
		 * @param a 透明度
		 * 
		 */		
		public function setBakColor(c:Number=0xffffff,a:Number=0.5,isBitmap:Boolean=false):void{
			clrBak()
			bakRender=new CRender();
			bakRender.init(0,0,{color:c,alpha:a,isBitmap:isBitmap},this.getShowWidth(),this.getShowHeight());
			this.addChild(bakRender);
			swapChildren_bakRender_spContent();
		}
		/**
		 * 清除背景 
		 * @return 
		 * 
		 */		
		public function clrBak():void{
			if(bakRender!=null){
				this.removeChild(bakRender);
				bakRender=null;
			}
		}
		/**
		 * 更新背景 
		 * 
		 */		
		private function updateBak():void{
			if(bakRender!=null) bakRender.setWH(this.getShowWidth(),this.getShowHeight());
		}
		
		/**
		 * 改变宽高
		 * @param w 宽    如果：宽为0,会保持以前的宽度
		 * @param h 高    如果：高为0,会保持以前的高度
		 * 
		 */
		override public function setWH(w:Number=0, h:Number=0):void{
			if(w==0) w=this.getShowWidth();
			if(h==0) h=this.getShowHeight();
			//
			if(spMask!=null){
				spMask.width=w;
				spMask.height=h;
			}
			//
			LT.init([[w],[h]],0,0);
			displayWidth=w;
			displayHeight=h;
			//CutLoad.CutLoad.debug("setWH:"+w+" "+h);
			update();	
			//更新背景
			updateBak()
		}
		/**
		 * 获得内部元件实例占领的宽度 
		 * @return 
		 * 
		 */
		public function getTakeWidth():Number{
			return this.takeWidth
		}
		/**
		 * 获得内部元件实例占领的高度
		 * @return 
		 * 
		 */
		public function getTakeHeight():Number{
			return this.takeHeight;
		}
		/**
		 * 设置透明度 
		 * @param a
		 * 
		 */		
		override public function setAlpha(a:Number):void{
			this.bakRender.setAlpha(a);
		}
		override public function getShowWidth():Number{
			return displayWidth;
		}
		override public function getShowHeight():Number{
			return displayHeight;
		}
		
	}
}